#include "mixerwidget.h"
#include "ui_mixerwidget.h"
#include "mixereditthemes.h"
#include "mixereditsentences.h"
#include "googleapi.h"
#include "translatewindow.h"
#include "defaultsettings.h"
#include "mixereditone.h"
#include <QMessageBox>

MixerWidget::MixerWidget(QWidget *parent) :
    QStackedWidget(parent),
    ui(new Ui::MixerWidget)
{
    ui->setupUi(this);
    setCurrentIndex(0);
    defaultQueryString = "SELECT sid, teng, thun, seng, grouping, shun FROM mix_sentences, mix_themes WHERE theme=tid";
    clearDisplayCounters();
    numberofSumSentences = 0;
    helpUsingNow = false;
    buttonsList << ui->mixButton0
                << ui->mixButton1
                << ui->mixButton2
                << ui->mixButton3
                << ui->mixButton4
                << ui->mixButton5
                << ui->mixButton6
                << ui->mixButton7
                << ui->mixButton8
                << ui->mixButton9
                << ui->mixButton10
                << ui->mixButton11
                << ui->mixButton12
                << ui->mixButton13
                << ui->mixButton14
                << ui->mixButton15
                << ui->mixButton16
                << ui->mixButton17;
    for (int i = 0; i < 18; ++i) {
        connect(buttonsList.at(i), SIGNAL(clicked()), this, SLOT(mixButtonsClicked()));
        connect(buttonsList.at(i), SIGNAL(rightClicked(QString)), this, SLOT(translateSlot(QString)));
    }
    ui->pushButton_Translate->setMenu(&translateMenu);
    localOptionsMenuList << ui->actionShow_Hungarian_sentence
                         << ui->actionUse_grouping
                         << ui->actionUseRightClickButtons;
    localOptionsMenu.addActions(localOptionsMenuList);
    ui->pushButton_LocalOptions->setMenu(&localOptionsMenu);
    localOptionsMenu.setStyleSheet(parent->styleSheet());
    translateMenu.setStyleSheet(parent->styleSheet());
    settingsLoad();
    startpanelFill();
}

MixerWidget::~MixerWidget()
{
    delete ui;
}

void MixerWidget::startpanelFill()
{
    themeSqlModel.setQuery("SELECT * FROM mix_themes ORDER BY teng");
    themeSqlModel.setHeaderData(1, Qt::Horizontal, tr("Theme-English"));
    themeSqlModel.setHeaderData(2, Qt::Horizontal, tr("Theme-Hungarian"));
    ui->tableView_ThemeSelector->setModel(&themeSqlModel);
    ui->tableView_ThemeSelector->hideColumn(0);
    ui->tableView_ThemeSelector->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
    ui->tableView_ThemeSelector->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
}

void MixerWidget::on_pushButtonClose_clicked()
{
    deleteLater();
}

void MixerWidget::on_commandLinkButtonStartMixer_clicked()
{
    currentQueryString = defaultQueryString;
    QStringList themeIdList_string;
    if (ui->radioButton_SelectedThemes->isChecked()) {
        QItemSelectionModel *selectionModel = ui->tableView_ThemeSelector->selectionModel();
        QModelIndexList indexes = selectionModel->selectedRows();
        int selnr = indexes.count();
        if (selnr > 0) {
            for (int i = 0; i < selnr; ++i)
                themeIdList_string << themeSqlModel.record(indexes.at(i).row()).value(0).toString();
            currentQueryString += " AND theme in (" + themeIdList_string.join(",") + ")";
        }
    }
    model.setQuery(currentQueryString);
    while (model.canFetchMore())
        model.fetchMore();
    numberofSumSentences = model.rowCount();
    if (numberofSumSentences == 0) {
        QString message(tr("Selection set is empty!\nChoose other selection or add themes/sentences using Edit buttons!"));
        QMessageBox::information(this, tr("Empty selection"), message);
        return;
    }
    QList<int> tmpSentenceIdList;
    for (int i = 0; i < numberofSumSentences; ++i)
        tmpSentenceIdList << model.record(i).value("sid").toInt();
    sentenceIdList.clear();
    if (ui->radioButton_AllSentences->isChecked())
        sentenceIdList = tmpSentenceIdList;
    else if (ui->radioButton_RandomFromAll->isChecked()) {
        for (int i = 0; i < ui->spinBox_Random->value(); ++i) {
            int tmpSIDListCount = tmpSentenceIdList.count();
            int value = tmpSentenceIdList.takeAt(qrand() % tmpSIDListCount);
            sentenceIdList.append(value);
        }
    }
    else if (ui->radioButton_RandomPerTheme->isChecked()) {
        QList<int> themeIdList_number;
        if (ui->radioButton_AllThemes->isChecked()) {
            QSqlQuery query("SELECT tid FROM mix_themes");
            while (query.next())
                themeIdList_number << query.value(0).toInt();
        }
        else
            for (int i = 0; i < themeIdList_string.count(); ++i)
                themeIdList_number << themeIdList_string.at(i).toInt();
        int numberOfUsedThemes = themeIdList_number.count();
        int needRecords = ui->spinBox_RandomPerTheme->value();
        for (int i = 0; i < numberOfUsedThemes; ++i) {
            QSqlQuery query;
            query.prepare("SELECT sid FROM mix_sentences where theme=:themeid");
            query.bindValue(0, themeIdList_number.at(i));
            query.exec();
            tmpSentenceIdList.clear();
            while (query.next())
                tmpSentenceIdList << query.value(0).toInt();
            int recordCount = 0;
            while (tmpSentenceIdList.count() && recordCount < needRecords) {
                ++recordCount;
                sentenceIdList << tmpSentenceIdList.takeAt(qrand() % tmpSentenceIdList.count());
            }
        }
    }
    numberofSumSentences = sentenceIdList.count();
    if (ui->radioButton_FreePlay->isChecked()) {
        ui->progressBar_Done->hide();
        ui->label_Playmode->setText(tr("Freeplay"));
    }
    else {
        ui->progressBar_Done->show();
        ui->progressBar_Done->setMaximum(numberofSumSentences);
        if (ui->checkBox_Learning->isChecked())
            ui->label_Playmode->setText(tr("Learning"));
        else
            ui->label_Playmode->setText(tr("All at Once"));
    }
    setCurrentIndex(1);
    clearDisplayCounters();
    isInGame = true;
    startNewSentence();
}

void MixerWidget::on_pushButtonCloseInGame_clicked()
{
    deleteLater();
}

void MixerWidget::on_pushButton_ChangeMode_clicked()
{
    setCurrentIndex(0);
}

void MixerWidget::getNewSentence(SentenceStrings &newstring, int currentID)
{
    int sentencesCount = sentenceIdList.count();
    if (currentID == 0) {
        currentListIndex = qrand() % sentencesCount;
        currentID = sentenceIdList.at(currentListIndex);
    }
    else
        currentListIndex = sentenceIdList.indexOf(currentID);
    currentSentenceID = currentID;
    currentSentenceIsOnlyTrue = true;
    int modelFullRowCount = model.rowCount();
    int selectedrow = 0;
    for (int i = 0; i < modelFullRowCount; ++i) {
        if (model.record(i).value("sid") == currentID) {
            selectedrow = i;
            break;
        }
    }
    newstring.sentenceEn = model.record(selectedrow).value("seng").toString().simplified();
    newstring.sentenceHu = model.record(selectedrow).value("shun").toString().simplified();
    newstring.themeEn = model.record(selectedrow).value("teng").toString().simplified();
    newstring.themeHu = model.record(selectedrow).value("thun").toString().simplified();
    newstring.sentenceGrouping = model.record(selectedrow).value("grouping").toString().simplified();
}

void MixerWidget::splitSentenceToWordlist(SentenceStrings &sStrings, QStringList &words)
{
    QStringList tmpsplit = sStrings.sentenceEn.split(" ");
    QQueue<QString> tmpwords;
    for (int i = 0; i < tmpsplit.count(); ++i)
        tmpwords.enqueue(tmpsplit.at(i));
    if (optionUseGrouping) {
        int grpstringlength = sStrings.sentenceGrouping.length();
        QList<int> grplist;
        for (int i = 0; i < grpstringlength; ++i)
            grplist.append(sStrings.sentenceGrouping.mid(i, 1).toInt());
        int tmpnumwords = tmpwords.count();
        int grpsum = 0;
        for (int i = 0; i < grplist.count(); ++i)
            grpsum += grplist.at(i);
        int cntgrp = 0;
        QQueue<QString> outlist;
        while (tmpnumwords && grpsum)
        {
            //normal grouping
            int currentgrpsize = grplist.at(cntgrp);
            QString currentgroup;
            for (int i = 0; i < currentgrpsize; ++i)
                if (tmpwords.count())
                {
                    currentgroup.append(tmpwords.dequeue() + " ");
                    --tmpnumwords;
                    --grpsum;
                }
            if (currentgrpsize)
                outlist.enqueue(currentgroup.trimmed());
            ++cntgrp;
        }
        while (outlist.count())
            words.append(outlist.dequeue());
    }
    while (tmpwords.count())
        words.append(tmpwords.dequeue());
    int numwords = words.count();
    if (numwords > 18)
    {
        QString w;
        w.append(words.at(17));
        while (numwords > 18)
        {
            w.append(" " + words.at(18));
            words.removeAt(18);
            --numwords;
        }
        words.replace(17, w);
    }
}

QString MixerWidget::strippingButtonWord(QString word)
{
    QString out;
    QRegExp rg;
    rg.setPattern("[.?!,]$");
    out = word.remove(rg);
    out = out.toLower();
    rg.setPattern(" i[' ]|^i$|^i[' ]| i$");
    int index = out.indexOf(rg, 0);
    while (index > -1) {
        if (out.at(index).isSpace())
            out.replace(index, 2, " I");
        else
            out.replace(index, 1, "I");
        index = out.indexOf(rg, index + 1);
    }
    return out;
}

void MixerWidget::startNewSentence(int currentID)
{
    SentenceStrings sStrings;
    correctSequence.clear();
    origWordList.clear();
    getNewSentence(sStrings, currentID);
    QString theme;
    theme.append(sStrings.themeEn);
    theme.append(" | ");
    theme.append(sStrings.themeHu);
    ui->label_ThemeName->setText(theme);
    ui->label_HunSentence->setText(sStrings.sentenceHu);
    ui->label_EnglishSentence->setText("");
    QStringList words;
    splitSentenceToWordlist(sStrings, words);
    int numwords = words.count();
    QList<int> tmpl;
    for (int i = 0; i < 18; ++i)
        tmpl.append(i);
    for (int i = 0; i < 100; ++i) {
        int p = qrand() % 18;
        tmpl.swap(0, p);
    }
    //clear translate actions list
    while (translateActionsList.count()) {
        delete translateActionsList.last();
        translateActionsList.removeLast();
        translateActionsListStrings.removeLast();
    }
    for (int i = 0; i < numwords; ++i) {
        int btn = tmpl.takeFirst();
        correctSequence.append(btn);
        origWordList.enqueue(words.at(i));
        buttonsList.at(btn)->setText(strippingButtonWord(words.at(i)));
        buttonsList.at(btn)->setFlat(false);
//        buttonsList.at(btn)->setStyleSheet("");
    }
    while (tmpl.count()) {
        int btn = tmpl.takeFirst();
        buttonsList.at(btn)->setText("");
        buttonsList.at(btn)->setFlat(true);
    }
    //Create translate actions
    for (int i = 0; i < 18; ++i) {
        QString currentButtonString(buttonsList.at(i)->text());
        if (currentButtonString.isEmpty())
            continue;
        if (!translateActionsListStrings.contains(currentButtonString)) {
            translateActionsListStrings.append(currentButtonString);
            translateActionsList.append(new QAction(currentButtonString, this));
            connect(translateActionsList.last(), SIGNAL(triggered()), this, SLOT(translateSlot()));
        }
    }
    translateMenu.addActions(translateActionsList);
}

void MixerWidget::translateSlot()
{
    QAction *clickedAction = qobject_cast<QAction*>(sender());
    QString text = clickedAction->text();
    TranslateWindow translateWindow(this, text);
    translateWindow.exec();
}

void MixerWidget::translateSlot(QString text)
{
    if (optionUseRightClickButtons) {
        if (text.isEmpty())
            return;
        TranslateWindow translateWindow(this, text);
        translateWindow.exec();
    }
}

void MixerWidget::mixButtonsClicked()
{
    if (correctSequence.isEmpty()) {
        if (isInGame)
            startNewSentence();
        return;
    }
    QString text;
    text = ui->label_EnglishSentence->text();
    QPushButton *clickedButton = qobject_cast<QPushButton*>(sender());
    bool correctBtn = false;
    if (clickedButton == buttonsList.at(correctSequence.first()))
        correctBtn = true;
    else if (clickedButton->text().compare(strippingButtonWord(origWordList.first())) == 0) {
        int clktocorrlist = 0;
        for (int i = 1; i < correctSequence.count(); ++i)
            if (buttonsList.at(correctSequence.at(i)) == clickedButton) {
                clktocorrlist = i;
                i = 18;
            }
        correctSequence.swap(0, clktocorrlist);
        correctBtn = true;
    }
    if (correctBtn) {
        text.append(origWordList.dequeue() + " ");
        ui->label_EnglishSentence->setText(text);
        clickedButton->setFlat(true);
        clickedButton->setText("");
        correctSequence.removeFirst();
        for (int i = 0; i < 18; ++i)
            if (! buttonsList.at(i)->text().isEmpty()) {
                buttonsList.at(i)->setFlat(false);
//                buttonsList.at(i)->setStyleSheet("");
            }
        if (helpUsingNow) {
            ++countUsedHelp;
            helpUsingNow = false;
            currentSentenceIsOnlyTrue = false;
        }
        else
            ++countCorrect;
    }
    else if (! clickedButton->isFlat()) {
//        clickedButton->setStyleSheet("color: rgb(221, 0, 22);");
        clickedButton->setFlat(true);
        ++countFalse;
        currentSentenceIsOnlyTrue = false;
    }
    if (correctSequence.isEmpty()) {
        if (ui->radioButton_FreePlay->isChecked())
            ++countDone;
        if (ui->radioButton_OneIsOneTimes->isChecked() && (! ui->checkBox_Learning->isChecked() || currentSentenceIsOnlyTrue)) {
            sentenceIdList.removeAt(currentListIndex);
            ++countDone;
        }
    }
    updateStatisticDisplays();
    if (sentenceIdList.count() == 0)
        isInGame = false;
}

void MixerWidget::on_pushButton_HelpOne_clicked()
{
    if ( ! correctSequence.isEmpty()) {
        helpUsingNow = true;
        buttonsList.at(correctSequence.first())->animateClick(200);
    }
}

void MixerWidget::on_toolButton_SpeechHU_clicked()
{
    QString text(ui->label_HunSentence->text());
    if (text.isEmpty())
        return;
    GoogleApi api;
    api.texttospeech("hu", text);
}

void MixerWidget::on_toolButton_SpeechEN_clicked()
{
    QString text(ui->label_EnglishSentence->text());
    if (text.isEmpty())
        return;
    GoogleApi api;
    api.texttospeech("en", text);
}

void MixerWidget::on_pushButton_EditThemes_clicked()
{
    MixerEditThemes editThemesDialog(this);
    editThemesDialog.exec();
    startpanelFill();
}

void MixerWidget::on_pushButton_EditSentences_clicked()
{
    MixerEditSentences editSentencesDialog(this);
    editSentencesDialog.exec();
}

void MixerWidget::on_pushButton_Next_clicked()
{
    if (isInGame)
        startNewSentence();
}

void MixerWidget::updateStatisticDisplays()
{
    ui->label_SentencesNr->setText(QString::number(numberofSumSentences));
    ui->label_Done->setText(QString::number(countDone));
    ui->label_Correct->setText(QString::number(countCorrect));
    ui->label_False->setText(QString::number(countFalse));
    ui->label_UsedHelp->setText(QString::number(countUsedHelp));
    int performancePercent = (countCorrect > 0) ? countCorrect*100/(countCorrect+countFalse+countUsedHelp) : 0;
    ui->label_Performance->setText(QString::number(performancePercent) + "%");
    ui->progressBarPerformance->setValue(performancePercent);
    if (ui->progressBar_Done->isVisible())
        ui->progressBar_Done->setValue(countDone);
}

void MixerWidget::clearDisplayCounters()
{
    countCorrect = 0;
    countDone = 0;
    countFalse = 0;
    countUsedHelp = 0;
    updateStatisticDisplays();
}

void MixerWidget::on_actionShow_Hungarian_sentence_toggled(bool checked)
{
    ui->label_HunSentence->setVisible(checked);
}

void MixerWidget::on_actionUse_grouping_toggled(bool checked)
{
    optionUseGrouping = checked;
    startNewSentence(currentSentenceID);
}

void MixerWidget::settingsLoad()
{
    settingsListMixer.clear();
    DefaultSettings def;
    settingsListMixer = def.getDefaultSettings("MIXER");
    int numberofsettings = settingsListMixer.count();
    QSqlQuery query("SELECT * from settings WHERE Pref_Category=\"MIXER\"");
    while (query.next()) {
        QStringList settingfromDB;
        settingfromDB << query.record().value("Pref_Category").toString()
                   << query.record().value("Pref_Key").toString()
                   << query.record().value("Pref_Value").toString();
        for (int i = 0; i < numberofsettings; ++i) {
            if (settingsListMixer.at(i).at(1) == settingfromDB.at(1)) {
                settingsListMixer[i][2] = settingfromDB.at(2);
                break;
            }
        }
    }
    foreach (QStringList onesetting, settingsListMixer) {
        if (onesetting.at(1) == "Use_Grouping") {
            bool usegrouping = false;
            if (onesetting.at(2) == "on")
                usegrouping = true;
            ui->actionUse_grouping->setChecked(usegrouping);
            optionUseGrouping = usegrouping;
        }
        else if (onesetting.at(1) == "Show_Hungarian") {
            bool showhunlabel = false;
            if (onesetting.at(2) == "on")
                showhunlabel = true;
            ui->actionShow_Hungarian_sentence->setChecked(showhunlabel);
            ui->label_HunSentence->setVisible(showhunlabel);
        }
        else if (onesetting.at(1) == "Right_Click_Translate") {
            bool useRightClickButtons = false;
            if (onesetting.at(2) == "on")
                useRightClickButtons = true;
            ui->actionUseRightClickButtons->setChecked(useRightClickButtons);
            optionUseRightClickButtons = useRightClickButtons;
        }
    }
}

void MixerWidget::settingsReloadFromMainSlot()
{
    ui->retranslateUi(this);
    settingsLoad();
    startNewSentence(currentSentenceID);
}

void MixerWidget::on_pushButton_EditThisSentence_clicked()
{
    MixerEditOne dialog(this, currentSentenceID);
    int result = dialog.exec();
    if (result == QDialog::Accepted) {
        dialog.writeDatatoDB();
        model.setQuery(currentQueryString);
        while (model.canFetchMore())
            model.fetchMore();
        startNewSentence(currentSentenceID);
    }
}

void MixerWidget::on_actionUseRightClickButtons_toggled(bool state)
{
    optionUseRightClickButtons = state;
}
